package evo.engine
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.Endian;
	import flash.utils.getTimer;

	public class AbstractDemo extends Sprite
	{	
		private var demoSync:Sequencer;
		protected var engine:DemoEngine;
		private var lastTime:int;
		private var fps:TextField;
		private var _lasttime:int=0;

		private var started:Boolean = false;
		private var showFps:Boolean;
				
		public function AbstractDemo(songUrl:String, demoSync:Sequencer, showFps:Boolean = false)
		{
			this.showFps  = showFps;
			if(showFps)
			{
				fps = new TextField();
			}
			// Load song and initialize beat sync
			this.demoSync = demoSync;
			this.demoSync.addEventListener("complete", songLoaded);
			this.demoSync.addEventListener(ProgressEvent.PROGRESS, progress);
			this.demoSync.addEventListener("ioError", songLoaded);
			this.demoSync.load(new URLRequest(songUrl));	
		}
		
		/**
		 * Makes final initialization of demo and starts running it
		 */
		private function startDemo():void
		{
			started=true;

			engine = new DemoEngine(800, 400);
			// Sets engines demosynchronization
			engine.setSynch(demoSync);
			// Initialize demo parts
			generateParts();
			// Engine is our only displayobject in whole demo, everything else is written into the displayobject buffer
			addChild(engine);
			// Starts running the actualy demo
			engine.startDemo();
		}
		
		/**
		 * Simple progressbar for loading the song
		 **/
		protected function progress(evt:ProgressEvent):void
		{
			this.graphics.clear();
			
			if((evt.bytesLoaded == evt.bytesTotal) && !started)
			{
				started = true;
				startDemo();
				return;
			}
			
            var percent:Number = evt.bytesLoaded / evt.bytesTotal;
            graphics.beginFill(0xFFFFFF);
            graphics.drawRect(800 * percent, 400 / 2 - 10,
                              800 * (1-percent), 20);
            graphics.endFill();
		}

		protected function songLoaded(evt:Event):void
		{
			if(evt.type == "ioError")
			{
				// Because song was not found, we se itTruePlay to false to use fallback timers to keep sync
				demoSync.isTruePlay = false;
				startDemo();
			}	

			if(showFps)
			{
				this.addChild(fps);
				this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
				fps.textColor = 0xffffff;
				fps.width = 200;
				fps.x = 700;		
			}
		}

		protected function onEnterFrame(evt:Event):void
		{
			if(showFps)
			{
				var time:uint=getTimer();
				fps.text = int((1000/(time-_lasttime))).toString();
				_lasttime=time;
			}
		}
		
		
		protected function generateParts():void
		{
			// NOP, handle stuff in actualy demos
		}
	}
}